#!/usr/bin/python

from multiplylib import *

# ============================== for 8x8/16x16 mix multiply ==============================
dots_grid_init(cols=33, rows=12)

# the dots only for "dot product"
dots_8x8_H = gen_pp(mcand_width=8, mplier_width=8, prefix="", pp0_height_reduction=True, pp_index_start=(4,8))
dots_empty =  gen_empty_dots_array()
dots_dotp_only = mix_dots(dots_8x8_H, dots_empty, "i_dotp")
fig1, ax1 = new_fig()
display_dots(dots_dotp_only, style="text")


dots_8x8_L = gen_pp(mcand_width=8, mplier_width=8, prefix="", pp0_height_reduction=True)
# set the last pp (not pp[4] but pp_8_L[4])
pp_8_L_4 = [("pp_8_L[4][%d]" % i,False) for i in range(8)]
set_pp(dots_8x8_L, row=4, pp_val=pp_8_L_4)
# # ext to 32 bits
# for col in range(16, 32):
#     set_dots_cell(dots_8x8_L, 0, col, ("1'b1", True))
# set_dots_cell(dots_8x8_L, 1, 16, ("Sc", True))


dots_8x8 = copy.deepcopy(dots_8x8_L)
for row in range(5):
    for col in range(16):
        dots_8x8[row+5][col] = dots_dotp_only[row][col]

for row in range(5):
    for col in range(16):
        dots_8x8[row][col+17] = dots_8x8_H[row][col]


fig3, ax3 = new_fig()
display_dots(dots_8x8, style="text")

# mark_dots(start_dot=(0,9))
# mark_dots(start_dot=(1,10))
# mark_dots(start_dot=(2,12))
# mark_dots(start_dot=(3,14))

# mark_dots(start_dot=(11,9))
# mark_dots(start_dot=(10,10))
# mark_dots(start_dot=(9,12))
# mark_dots(start_dot=(8,14))

# set_dots_cell(dots_8x8, 0, 9, (0, False))
# set_dots_cell(dots_8x8, 1, 10, (0, False))
# set_dots_cell(dots_8x8, 2, 12, (0, False))
# set_dots_cell(dots_8x8, 3, 14, (0, False))

# set_dots_cell(dots_8x8, 11, 9, (0, False))
# set_dots_cell(dots_8x8, 10, 10, (0, False))
# set_dots_cell(dots_8x8, 9, 12, (0, False))
# set_dots_cell(dots_8x8, 8, 14, (0, False))

# set_dots_cell(dots_8x8, 0, 15, ("op_dotp", True))
# set_dots_cell(dots_8x8, 0, 14, ("{~op_dotp}", True))
# set_dots_cell(dots_8x8, 0, 13, ("op_dotp", True))
# set_dots_cell(dots_8x8, 0, 12, ("{~op_dotp}", True))
# set_dots_cell(dots_8x8, 0, 11, ("op_dotp", True))
# set_dots_cell(dots_8x8, 0, 10, ("1'b1", True))
# set_dots_cell(dots_8x8, 0, 9, ("{~op_dotp}", True))


# # # the "1" that could be counteracted
# mark_dots(start_dot=(0,31), end_dot=(0,25))
# mark_dots(start_dot=(2,25))

# for col in range(31,25-1,-1):
#     set_dots_cell(dots_8x8, 0, col, (0, False))
# set_dots_cell(dots_8x8, 2, 25, (0, False))


dots_8x8_up = reorg_upward(dots_8x8)
fig5, ax5 = new_fig()
display_dots(dots_8x8_up, style="dot")


dots_16x16 = gen_pp(mcand_width=16, mplier_width=16, prefix="")
# # for round when in fixed point mode          ---- add it at the last 
# set_dots_cell(dots_16x16, 9, 14, ("i_round", True))
# # only for round mode of msub of fixed point num
# for col in range(15,31+1):
#     set_dots_cell(dots_16x16, 9, col, ("i_sub_round", True))


dots_16x16_up =reorg_upward(dots_16x16)
display_dots(dots_16x16_up, fill=False, color="red", style="dot")

dots_mix = mix_dots(dots_8x8_up, dots_16x16_up, "mode8")


# only for round of mul/madd/msub when in fixed point mode
set_dots_cell(dots_mix, 9, 14, ("i_round", True))
# only for round of msub of fixed point num
for col in range(15,31+1):
    set_dots_cell(dots_mix, 9, col, ("i_msub_round", True))

fig6, ax6 = new_fig()
display_dots(dots_mix, style="text")

mark_dots(start_dot=(9,14), end_dot=(9,31))


# # dot product must use in 8x8 mode
# # strip "(mode8 & (i_dotp & pp[x][x]))" down to "(i_dotp & pp[x][x])"
# for i in all_dots(dots_mix):
#     if i[0] != 0 and i[0].find("(mode8 & (i_dotp &") == 0:
#         print (i[0][9:-1], i[1])
def dot_process(item):
    if item.find("(mode8 & (i_dotp &") == 0:
        return item[9:-1]
    
traverse_dots(dots_mix, dot_process)


print "==================== row formula of 8x8/16x16 mix multiply ===================="
print_row_formula(dots_mix, prefix="assign pp_ext")
print "==============================================================================="

show()
exit()
